using System;
using System.Collections.Generic;
using System.Linq;

namespace ArmyManager.Items
{
	public class Item
	{
		#region Static and Nested Members

		public enum ItemTypes
		{
			Weapon,
			Armor,
			Helmet,
			Necklace,
			Ring,
			Boots
		}

		public static readonly Dictionary<ItemTypes, Item> NullItems = new Dictionary<ItemTypes, Item>();

		static Item()
		{
			foreach (ItemTypes itemType in Enum.GetValues(typeof(ItemTypes)).OfType<ItemTypes>())
			{
				NullItems[itemType] = new Item("None", itemType, canKeep: false);
			}
		}

		#endregion

		private List<ItemAttribute> _attributes;
		
		public string Name { get; private set; }
		public ItemTypes ItemType { get; private set; }
		// Is it a lose-on-unequip item
		public bool CanKeep { get; private set; }
		public List<ItemAttribute> Attributes { get { return _attributes; } }

		protected Item() { }

		public Item(string name, ItemTypes itemType, List<ItemAttribute> attributes = null, bool canKeep = true)
		{
			Name = name;
			ItemType = itemType;
			_attributes = attributes ?? new List<ItemAttribute>();
			CanKeep = canKeep;
		}

		public IEnumerable<ItemAttribute> GetFusionAttributes()
		{
			List<ItemAttribute> fusionAttributes = new List<ItemAttribute>(_attributes.Capacity);
			foreach (ItemAttribute attribute in _attributes)
			{
				fusionAttributes.Add(attribute.ReduceForFusion());
			}
			return fusionAttributes;
		}

		public void FuseAttributes(IEnumerable<ItemAttribute> attributes)
		{
			List<ItemAttribute> newAttributes = new List<ItemAttribute>();
			foreach (ItemAttribute attribute in attributes)
			{
				ItemAttribute currentAttribute = _attributes.FirstOrDefault(a => a.AttributeType == attribute.AttributeType);
				if (currentAttribute != null)
				{
					currentAttribute.AddAmount(attribute.Amount);
				}
				else
				{
					newAttributes.Add(attribute);
				}
			}
			_attributes.AddRange(newAttributes);
		}

		public static Item operator +(Item primaryItem, Item secondaryItem)
		{
			Item newItem = primaryItem.Clone();
			newItem.FuseAttributes(secondaryItem.GetFusionAttributes());
			return newItem;
		}

		public Item Clone()
		{
			Item newItem = CloneInternal();
			newItem.Name = Name;
			newItem.ItemType = ItemType;
			newItem.CanKeep = CanKeep;
			newItem._attributes = Attributes.Select(a => a.Clone()).ToList();
			return newItem;
		}

		protected virtual Item CloneInternal()
		{
			return new Item();
		}
	}
}